package com.mars.miaosha.config;

import com.mars.miaosha.domain.MiaoshaUser;
import com.mars.miaosha.service.MiaoshaUserService;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * 将MiaoshaUser作为参数传入到方法参数中，直接使用，脱离request,response一直跟随程序的繁重
 *
 * @author MARS
 * @date 2018/5/9
 */

@Service
public class UserArgumentResolver implements HandlerMethodArgumentResolver{

    @Autowired
    private MiaoshaUserService miaoshaUserService;

    /**
     * supportsParameter():用于判定是否需要处理该参数分解，返回true为需要，并会去调用下面的方法resolveArgument。
     * @param methodParameter
     * @return
     */
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        // 获取参数类型
        Class<?> clazz = methodParameter.getParameterType();
        // 如果参数类型 == 秒杀User,返回true，执行下面的方法resolveArgument()
        return clazz == MiaoshaUser.class;
    }

    /**
     * resolveArgument():真正用于处理参数分解的方法，返回的Object就是controller方法上的形参对象。
     * @param methodParameter
     * @param modelAndViewContainer
     * @param nativeWebRequest
     * @param webDataBinderFactory
     * @return
     * @throws Exception
     */
    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        // 获取request、response
        HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
        HttpServletResponse response = nativeWebRequest.getNativeResponse(HttpServletResponse.class);
        // 获取token信息
        String paramToken = request.getParameter(MiaoshaUserService.COOKIE_NAME_TOKEN);
        String cookieToken = getCookieValue(request,MiaoshaUserService.COOKIE_NAME_TOKEN);
        if(StringUtils.isEmpty(cookieToken) && StringUtils.isEmpty(paramToken)){
            return null;
        }
        // 获取token
        String token = StringUtils.isEmpty(paramToken) ? cookieToken : paramToken;
        return miaoshaUserService.getByToken(response,token);
    }

    private String getCookieValue(HttpServletRequest request, String cookieNameToken) {
        // 获取所有的cookie
        Cookie[] cookies = request.getCookies();
        if (cookies ==null || cookies.length <=0) {
            return null;
        }
        // 遍历cookie
        for (Cookie cookie : cookies ) {
            if (cookie.getName().endsWith(cookieNameToken)) {
                return cookie.getValue();
            }
        }
        return null;
    }
}
